We gebruiken de functies uit tidyverse om makkelijk data te transformeren (dplyr) en te visualiseren (ggplot). Met plotly kunnen de grafieken eenvoudig interactief gemaakt.
De data komt uit de database van een HRM-systeem en bevat functiegegevens en verzuimdata. Het betreft hier een bancaire organisatie.
myDF <- read.csv2("hra-data.csv")
head(myDF)
summary(myDF)
Peildatum Stam.nummer Stromen Naam Man.Vrouw
31-01-2014:1744 Min. : 1.0 :4081 a : 698 Man :4023
31-01-2015:1934 1st Qu.: 319.5 - : 4 o : 400 Vrouw:4360
31-01-2016:2444 Median : 591.0 Doorstroom IN :2123 e : 396
31-01-2017:2261 Mean : 590.2 Doorstroom UIT:1705 h : 396
3rd Qu.: 852.0 Instroom : 305 n : 381
Max. :2465.0 Uitstroom : 165 k : 377
(Other):5735
Geboortedatum Leeftijd Dienst.jaren Organisatie
04-04-1986: 19 Min. :20.20 Min. : 0.100 Banking:8383
10-07-1954: 19 1st Qu.:37.85 1st Qu.: 2.700
02-09-1963: 18 Median :47.50 Median : 6.200
03-05-1965: 18 Mean :46.27 Mean : 8.964
30-03-1976: 18 3rd Qu.:54.50 3rd Qu.:12.500
15-04-1953: 17 Max. :71.20 Max. :35.900
(Other) :8274
Organisatie.niveau.1 Organisatie.niveau.2
Banking and Payment:6272 Business Support Services:1574
Corporate Services :2111 Private Banking :1307
Domestic Markets :1278
Investments :1213
Securities : 692
Auditing : 595
(Other) :1724
Organisatie.niveau.3 Functie Garantieschaal
Business Support Services:1573 Business Banker :3197 Min. : 2.00
Domestic Markets :1048 Consumer Banker :1700 1st Qu.: 9.00
Large Accounts : 848 Administration officer: 556 Median :11.00
National Investments : 657 Investment officer : 351 Mean :10.42
Agriculture Credit : 560 Investment assistant : 240 3rd Qu.:12.00
Bank and Trusts : 464 Business Broker : 194 Max. :18.00
(Other) :3233 (Other) :2145
Functieschaal FTE Type.Contract Type.Arbeidsovereenkomst
Min. : 1.00 Min. :0.0250 Tijdelijk:1358 D2:7027
1st Qu.: 9.00 1st Qu.:0.6000 Vast :7025 D3: 206
Median :11.00 Median :0.8000 D4:1150
Mean :10.24 Mean :0.7624
3rd Qu.:12.00 3rd Qu.:1.0000
Max. :17.00 Max. :1.0000
Hoogstgenoten.opleiding Aantal.ziekmeldingen Dagen.afwezig Leidinggevende
:1674 - :3895 - :3575 - :2631
Associate : 981 1 :2195 3,00 : 218 780 : 286
Bachelor :2660 2 :1284 1,00 : 203 781 : 247
Master :2875 3 : 592 2,00 : 198 184 : 246
Ph.D/Doctoral: 193 4 : 267 4,00 : 180 608 : 240
5 : 93 6,00 : 158 655 : 216
(Other): 57 (Other):3851 (Other):4517
Naam.leidingegevende Einddatum.Bepaalde.Tijd
- :2639 31-12-2099:6949
m : 995 14-03-2015: 184
l : 570 13-03-2016: 134
j : 460 14-04-2015: 103
r : 430 13-03-2017: 92
o : 376 13-04-2016: 68
(Other):2913 (Other) : 853
Een aantal variabelen moet worden omgezet naar het juiste datatype. De variabelen met tijdsinformatie moeten worden omgezet naar het type Date en sommige variabelen die eigenlijk numeriek zijn worden als tekst beschouwd.
Er zijn vier peildata. Voor dit onderzoek beperken we ons tot de record van het laatste jaar. Onder de laatst peildatum staan personen die voor de startdatum van het jaar uit dienst zijn getreden. Bovendien zitten er dubbelingen in set. Na toepassing van een filter blijven de juiste records over.
We voegen nog twee kolommen toe: een kolom aantal contractuele werkdagen en het effectief aantal ziektedagen. Hiervoor gebruiken we de formules van het CBS.
myDF$Peildatum <- as.Date(myDF$Peildatum, format="%d-%m-%Y")
myDF$Geboortedatum <- as.Date(myDF$Geboortedatum, format="%d-%m-%Y")
myDF$Einddatum.Bepaalde.Tijd <- as.Date(myDF$Einddatum.Bepaalde.Tijd, format="%d-%m-%Y")
myDF$Stromen <- gsub(" ", "", myDF$Stromen)
myDF$Aantal.ziekmeldingen <- gsub("-", "", myDF$Aantal.ziekmeldingen)
myDF$Aantal.ziekmeldingen <- as.numeric(gsub(",", ".", myDF$Aantal.ziekmeldingen))
myDF$Dagen.afwezig <- gsub("-", "", myDF$Dagen.afwezig)
myDF$Dagen.afwezig <- as.numeric(gsub(",", ".", myDF$Dagen.afwezig))
# # Sommige personen hebben de organisatie eerder verlaten
start.date <- as.Date("2016-01-31")
myDF <- myDF %>% filter(Peildatum == "2017-01-31", Einddatum.Bepaalde.Tijd > start.date, Stromen == "")
myDF <- mutate(myDF, FTE.x.werkdagen=FTE*365, FTE.x.ziektedagen=FTE*Dagen.afwezig)
summary(myDF)
Peildatum Stam.nummer Stromen Naam Man.Vrouw
Min. :2017-01-31 Min. : 1.0 Length:1064 a : 93 Man :498
1st Qu.:2017-01-31 1st Qu.: 342.8 Class :character h : 52 Vrouw:566
Median :2017-01-31 Median : 628.5 Mode :character o : 52
Mean :2017-01-31 Mean : 627.1 e : 50
3rd Qu.:2017-01-31 3rd Qu.: 927.2 d : 49
Max. :2017-01-31 Max. :1230.0 q : 49
(Other):719
Geboortedatum Leeftijd Dienst.jaren Organisatie
Min. :1945-11-01 Min. :24.20 Min. : 1.100 Banking:1064
1st Qu.:1960-10-26 1st Qu.:40.80 1st Qu.: 2.800
Median :1966-12-06 Median :50.15 Median : 6.400
Mean :1968-07-20 Mean :48.53 Mean : 9.247
3rd Qu.:1976-03-30 3rd Qu.:56.30 3rd Qu.:12.700
Max. :1992-12-06 Max. :71.20 Max. :35.900
Organisatie.niveau.1 Organisatie.niveau.2
Banking and Payment:811 Business Support Services:287
Corporate Services :253 Investments :164
Private Banking :151
Domestic Markets :113
Securities : 82
Auditing : 67
(Other) :200
Organisatie.niveau.3 Functie Garantieschaal
Business Support Services:287 Business Banker :362 Min. : 2.00
Large Accounts :100 Consumer Banker :239 1st Qu.: 9.00
International Investments: 91 Administration officer: 84 Median :11.00
Domestic Markets : 89 Investment officer : 42 Mean :10.45
Corporate Investments : 64 Business Broker : 36 3rd Qu.:12.00
Bank and Trusts : 63 Investment assistant : 35 Max. :18.00
(Other) :370 (Other) :266
Functieschaal FTE Type.Contract Type.Arbeidsovereenkomst
Min. : 1.00 Min. :0.0250 Tijdelijk:160 D2:904
1st Qu.: 9.00 1st Qu.:0.6000 Vast :904 D3: 23
Median :11.00 Median :0.8000 D4:137
Mean :10.25 Mean :0.7629
3rd Qu.:12.00 3rd Qu.:1.0000
Max. :17.00 Max. :1.0000
Hoogstgenoten.opleiding Aantal.ziekmeldingen Dagen.afwezig Leidinggevende
:222 Min. :1.000 Min. : 0.00 - :325
Associate :126 1st Qu.:1.000 1st Qu.: 2.40 1175 : 37
Bachelor :328 Median :1.000 Median : 5.60 184 : 33
Master :362 Mean :1.842 Mean : 20.98 1179 : 30
Ph.D/Doctoral: 26 3rd Qu.:2.000 3rd Qu.: 14.00 1178 : 28
Max. :7.000 Max. :380.52 780 : 27
NA's :501 NA's :461 (Other):584
Naam.leidingegevende Einddatum.Bepaalde.Tijd FTE.x.werkdagen FTE.x.ziektedagen
- :326 Min. :2016-12-12 Min. : 9.125 Min. : 0.00
m :131 1st Qu.:2099-12-31 1st Qu.:219.000 1st Qu.: 1.92
l : 76 Median :2099-12-31 Median :292.000 Median : 4.48
a : 65 Mean :2086-11-23 Mean :278.476 Mean : 17.09
r : 54 3rd Qu.:2099-12-31 3rd Qu.:365.000 3rd Qu.: 12.00
j : 52 Max. :2099-12-31 Max. :365.000 Max. :380.52
(Other):360 NA's :461
Door de som van de laatste twee kolommen op elkaar te delen, krijgen we het verzuimpercentage.
tot.aant.ziektedagen <- sum(myDF$FTE.x.ziektedagen, na.rm = TRUE)
tot.aant.werkdagen <- sum(myDF$FTE.x.werkdagen)
ziekteverzuim = tot.aant.ziektedagen / tot.aant.werkdagen
tot.aant.ziektedagen
[1] 10307.52
tot.aant.werkdagen
[1] 296298.6
ziekteverzuim
[1] 0.0347876
Nu de data opgeschoond is, kunnen we kijken of er opvallende patronen te ontdekken zijn.
Tot aan de leeftijdsgrens van 50 zijn er meer vrouwen dan mannen. Binnen de organisatie werken al meer vrouwen dan mannen. Als het doorstroompatroon voor beide geslachten gelijk blijft zal het aantal vrouwen in de organisatie nog meer toenemen.
p1 <- ggplot(myDF) +
geom_freqpoly(aes(x=Leeftijd, color = Man.Vrouw), binwidth = 2)
ggplotly(p1, width = 800)
p2 <- ggplot(myDF) +
geom_boxplot(aes(x=Man.Vrouw, y=Leeftijd, fill=Man.Vrouw))
ggplotly(p2, width = 800)
Oudere wernemers neigen zich langer ziek te melden. Of er een statistisch relevante relatie is, moet nog blijken.
p3 <- ggplot(myDF, aes(x=Leeftijd, y=Dagen.afwezig)) +
geom_point() +
geom_smooth(method='lm')
ggplotly(p3, width = 800)
Removed 461 rows containing non-finite values (stat_smooth).
Bij ‘Banking and Payment’ lijken werknemers het langste ziek te zijn. Ook deze relatie moet nog nader onderzocht worden, voordat dit definitief gesteld kan worden.
p4 <- ggplot(myDF) +
geom_point(aes(x=Organisatie.niveau.1 , y=Dagen.afwezig, fill=Type.Contract))
ggplotly(p4, width = 800)
Er is een duidelijk aanwijzing dat vrouwen meer part-time werken dan mannen. Echter dit moet nog getoetst worden.
p4 <- ggplot(myDF) +
geom_boxplot(aes(x=Man.Vrouw , y=FTE, fill=Man.Vrouw))
ggplotly(p4, width = 800)
grpMV <- group_by(myDF, Man.Vrouw)
summarize(grpMV, Aantal = n(), Gem.Leeftijd = mean(Leeftijd))
summarize(grpMV, Aantal = n(), Gem.dgn.afw = mean(Dagen.afwezig, na.rm = TRUE))
grpTC <- group_by(myDF, Type.Contract)
summarize(grpTC, Aantal = n(), Gem.Leeftijd = mean(Leeftijd))
summarize(grpTC, Aantal = n(), Gem.dgn.afw = mean(Dagen.afwezig, na.rm = TRUE))
Eerder konden een aantal patronen visueel worden waargenomen. Hieronder worden ze getoetst m.b.v. ANOVA. Uiteindelijk blijkt er een statistische relatie te zijn tussen FTE en geslacht. De bijbehorende boxplot deed dit al vermoeden. Ook is er een statistisch significante positieve relatie tussen leeftijd en ziekteverzuim: met iedere tien jaar neemt het gemiddeld aantal ziektedagen met vijf toe.
m1<- aov(Dagen.afwezig ~ Type.Contract, data = myDF)
summary(m1)
Df Sum Sq Mean Sq F value Pr(>F)
Type.Contract 1 705 704.7 0.352 0.553
Residuals 601 1202574 2001.0
461 observations deleted due to missingness
m2<- aov(Dagen.afwezig ~ Organisatie.niveau.1, data = myDF)
summary(m2)
Df Sum Sq Mean Sq F value Pr(>F)
Organisatie.niveau.1 1 261 261.2 0.13 0.718
Residuals 601 1203018 2001.7
461 observations deleted due to missingness
m3<- aov(FTE ~ Man.Vrouw, data = myDF)
summary(m3)
Df Sum Sq Mean Sq F value Pr(>F)
Man.Vrouw 1 5.61 5.608 105.5 <2e-16 ***
Residuals 1062 56.43 0.053
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
plot(TukeyHSD(m3, conf.level = 0.99),las=1, col = "red")
m4 <- glm(Dagen.afwezig ~ Leeftijd, data = myDF)
summary(m4)
Call:
glm(formula = Dagen.afwezig ~ Leeftijd, data = myDF)
Deviance Residuals:
Min 1Q Median 3Q Max
-28.56 -18.83 -13.42 -4.52 354.02
Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) -4.327 8.810 -0.491 0.62353
Leeftijd 0.537 0.183 2.935 0.00347 **
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
(Dispersion parameter for gaussian family taken to be 1973.845)
Null deviance: 1203279 on 602 degrees of freedom
Residual deviance: 1186281 on 601 degrees of freedom
(461 observations deleted due to missingness)
AIC: 6290.6
Number of Fisher Scoring iterations: 2